package cn.klaw.selenium.driver;

import cn.klaw.selenium.properties.SeleniumProperties;
import cn.klaw.selenium.SeleniumHelper;
import cn.klaw.selenium.consts.SeleniumConsts;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.remote.AbstractDriverOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.service.DriverService;

@Data
@Slf4j
public abstract class AbstractBrowser<D extends RemoteWebDriver, S extends DriverService, O extends AbstractDriverOptions<?>> implements SeleniumBrowser<D, S, O> {

    protected D driverInstance;
    protected S driverServiceInstance;
    protected O driverOptionsInstance;


    protected AbstractBrowser() {
        this(null, null, null);
    }

    protected AbstractBrowser(D driver, S driverService, O driverOptions) {
        this.driverInstance = driver;
        this.driverServiceInstance = driverService;
        this.driverOptionsInstance = driverOptions;
        if (this.driverInstance == null) {
            if (this.driverServiceInstance == null && this.driverOptionsInstance == null) {
                this.driverServiceInstance = buildDriverService();
                this.driverOptionsInstance = buildDriverOptions();
            }
            if(log.isDebugEnabled()){
                log.debug(SeleniumConsts.MARKER, "创建浏览器, {}, {}", this.driverServiceInstance, this.driverOptionsInstance);
            }
            this.driverInstance = buildDriver(this.driverServiceInstance, this.driverOptionsInstance);
        }
    }

    protected static SeleniumProperties getProperties() {
        return SeleniumHelper.getSeleniumProperties();
    }

    protected abstract O buildDriverOptions();

    protected abstract S buildDriverService();

    protected abstract D buildDriver(S driverService, O driverOptions);

    D buildDriver() {
        return buildDriver(buildDriverService(), buildDriverOptions());
    }


    @Override
    public D getDriver() {
        return this.driverInstance;
    }

    @Override
    public S getDriverService() {
        return this.driverServiceInstance;
    }

    @Override
    public O getDriverOptions() {
        return this.driverOptionsInstance;
    }


    /**
     * 初始化调用
     */
    public void init() {
        if(log.isDebugEnabled()){
            log.debug(SeleniumConsts.MARKER, "浏览器实例初始化方法调用");
        }
        if(driverInstance != null) {
            setScriptTimeout(getProperties().getScriptTimeout());
            setPageLoadTimeout(getProperties().getPageLoadTimeout());
            setImplicaitlyWaitTimeout(getProperties().getImplicaitlyWaitTimeout());
        }
    }

    @Override
    public void close() {
        if(log.isDebugEnabled()){
            log.debug(SeleniumConsts.MARKER, "浏览器实例销毁化方法调用");
        }
        if (driverInstance != null) {
            try {
                driverInstance.quit();
            } catch (Exception e) {
                log.error(SeleniumConsts.MARKER, "关闭浏览器出错", e);
            }
        }
    }
}
